package top.ddandang.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import top.ddandang.blog.model.pojo.User;
import top.ddandang.blog.mapper.UserMapper;
import top.ddandang.blog.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import top.ddandang.blog.utils.OssUtil;
import top.ddandang.blog.utils.RedisUtil;
import top.ddandang.blog.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author D
 * @since 2020-06-23
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private TokenUtil tokenUtil;

    @Resource
    private OssUtil ossUtil;

    /**
     * 保存用户token的key值 token:ID
     */
    private final String tokenKey = "token:";

    private final String path = "blog/images/user/";

    /**
     * 总用户数的key值
     */
    private final String totalUserKey = "totalUser";


    @Override
    public User getUser(String username) {
        User user = null;
        String key = "user:" + username;

        //判断缓存是否存在
        if(redisUtil.hasKey(key)) {
            user = (User)redisUtil.get(key);
        }else {
            //从数据库中查找
            user = userMapper.selectOne(
                    new QueryWrapper<User>().
                            eq("username", username)
            );
            if(user !=null ){
                //存入缓存 12小时
                redisUtil.set(key, user, 12);
            }

        }
        return user;
    }

    @Override
    public int insertUser(String nickname, String username, String password, String passwordCheck) {

        //两次密码不同
        if(!password.equals(passwordCheck)) {
            return 400;
        }
        User user = new User();
        user.setNickname(nickname)
                .setUsername(username)
                .setPassword(password);
        while (true) {
            if(userMapper.insert(user) == 1) {
                break;
            }
        }
        //统计注册的用户
        String key = "totalUser";
        redisUtil.increment(key, 1);
        return 1;
    }

    @Override
    public String createToken(User user) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", user.getId());
        map.put("nickname", user.getNickname());
        map.put("username", user.getUsername());
        map.put("password", user.getPassword());
        map.put("position", user.getPosition());
        return tokenUtil.createToken(map);
    }

    @Override
    public String upLoadUserAvatar(MultipartFile file) {
        return ossUtil.uploadImage(file, path);
    }

    @Async
    @Override
    public void updateUserAvatar(String url, String username) {
        String key = "user:" + username;
        userMapper.update(null, new UpdateWrapper<User>()
        .eq("username", username)
        .set("avatar", url));
        if(redisUtil.hasKey(key)) {
            redisUtil.del(key);
        }
    }

    @Override
    public int updateNickname(String nickname, String username) {

        String key = "user:" + username;
        int flag = userMapper.update(null, new UpdateWrapper<User>()
                .eq("username", username)
                .set("nickname", nickname));
        if(redisUtil.hasKey(key)) {
            redisUtil.del(key);
        }
        return flag;
    }

    @Override
    public Boolean judgePassword(String oldPassword, String username) {

        User user = new User();
        String key = "user:" + username;
        if(redisUtil.hasKey(key)) {
            user = (User) redisUtil.get(key);
        }else {
            user = userMapper.selectOne(new QueryWrapper<User>()
            .eq("username", username));
        }
        return oldPassword.equals(user.getPassword());

    }

    @Override
    public int updatePassword(String password, String username) {

        String key = "user:" + username;
        int flag = userMapper.update(null, new UpdateWrapper<User>()
                .eq("username", username)
                .set("password", password));
        if(redisUtil.hasKey(key)) {
            redisUtil.del(key);
        }
        return flag;
    }

    @Override
    public void logOut(Integer userId) {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        String key = tokenKey + userId;
        redisUtil.del(key);
    }

    @Override
    public int getUserAmount() {
        int userAmount = userMapper.getUserAmount();
        redisUtil.set(totalUserKey, userAmount);
        return userAmount;
    }
}
